package com.shitou.springai1.user.service;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.shitou.springai1.user.entity.IntentResult;
import com.shitou.springai1.user.entity.IntentType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

// IntentRecognitionService.java
@Service
@Slf4j
public class IntentRecognitionService {

    @Autowired
    private ChineseSegmentService segmentService;

    // 位置相关关键词
    private static final Set<String> LOCATION_KEYWORDS = Set.of(
        "在哪", "位置", "地址", "什么地方", "怎么走", "如何去", "路线",
        "办公室", "教室", "实验室", "会议室", "楼", "栋", "层", "室", "房",
            "鹏云一","鹏云二","鹏云三","鹏云四","诚远楼","图书馆"
    );

    // 人员相关关键词
    private static final Set<String> PEOPLE_KEYWORDS = Set.of(
        "老师", "教授", "班主任", "辅导员", "主任", "书记", "院长","副院长", "校长",
        "学生", "同学", "新生", "老生", "研究生", "博士生"
    );

    // 流程相关关键词
    private static final Set<String> PROCEDURE_KEYWORDS = Set.of(
        "怎么办", "如何", "流程", "步骤", "手续", "申请", "提交", "交给",
        "办理", "处理", "完成", "需要", "材料", "文件", "档案"
    );

    public IntentResult analyzeIntent(String userInput) {
        if (StringUtils.isBlank(userInput)) {
            return new IntentResult(IntentType.UNKNOWN, new ArrayList<>(),
                    new HashMap<>(), 0.0, "", userInput);
        }

        log.info("开始意图分析: {}", userInput);

        List<String> keywords = segmentService.extractKeywords(userInput);
        List<IntentType> detectedIntents = new ArrayList<>();
        Map<String, String> entities = new HashMap<>();

        // 检测意图
        double locationScore = calculateIntentScore(keywords, LOCATION_KEYWORDS);
        double peopleScore = calculateIntentScore(keywords, PEOPLE_KEYWORDS);
        double procedureScore = calculateIntentScore(keywords, PROCEDURE_KEYWORDS);

        // 根据分数确定意图
        if (locationScore > 0.3) {
            detectedIntents.add(IntentType.LOCATION_QUERY);
        }
        if (peopleScore > 0.3) {
            detectedIntents.add(IntentType.PEOPLE_QUERY);
        }
        if (procedureScore > 0.3) {
            detectedIntents.add(IntentType.PROCEDURE_QUERY);
        }

        // 提取实体
        extractEntities(userInput, keywords, entities);

        // 确定主要意图
        IntentType primaryIntent = determinePrimaryIntent(detectedIntents,
                locationScore, peopleScore, procedureScore);

        // 重写查询
        String rewrittenQuery = rewriteQuery(primaryIntent, keywords, entities);

        double confidence = calculateConfidence(primaryIntent, locationScore,
                peopleScore, procedureScore);

        IntentResult result = new IntentResult(primaryIntent, detectedIntents,
                entities, confidence, rewrittenQuery, userInput);

        log.info("意图分析结果: {}", result);
        return result;
    }

    private double calculateIntentScore(List<String> keywords, Set<String> intentKeywords) {
        long matchCount = keywords.stream()
                .filter(intentKeywords::contains)
                .count();
        return (double) matchCount / keywords.size();
    }

    private void extractEntities(String userInput, List<String> keywords, Map<String, String> entities) {
        // 提取人员实体
        extractPeopleEntities(keywords, entities);

        // 提取位置实体
        extractLocationEntities(keywords, entities);

        // 从原始输入中提取更精确的实体信息
        extractFromOriginalInput(userInput, entities);
    }

    private void extractPeopleEntities(List<String> keywords, Map<String, String> entities) {
        Set<String> peopleTerms = keywords.stream()
                .filter(PEOPLE_KEYWORDS::contains)
                .collect(Collectors.toSet());

        if (!peopleTerms.isEmpty()) {
            entities.put("person_role", String.join(",", peopleTerms));
        }
    }

    private void extractLocationEntities(List<String> keywords, Map<String, String> entities) {
        Set<String> locationTerms = keywords.stream()
                .filter(LOCATION_KEYWORDS::contains)
                .collect(Collectors.toSet());

        if (!locationTerms.isEmpty()) {
            entities.put("location_type", String.join(",", locationTerms));
        }

        // 提取具体的建筑或房间号（包含数字的词）
        List<String> specificLocations = keywords.stream()
                .filter(term -> term.matches(".*\\d+.*") || term.length() >= 2)
                .filter(term -> !LOCATION_KEYWORDS.contains(term) && !PEOPLE_KEYWORDS.contains(term))
                .collect(Collectors.toList());

        if (!specificLocations.isEmpty()) {
            entities.put("specific_location", String.join(",", specificLocations));
        }
    }

    private void extractFromOriginalInput(String userInput, Map<String, String> entities) {
        // 使用正则表达式提取更精确的信息
        extractWithPatterns(userInput, entities);
    }

    private void extractWithPatterns(String userInput, Map<String, String> entities) {
        // 匹配建筑+房间号模式，如"城远楼405"
        Pattern buildingRoomPattern = Pattern.compile("([\\u4e00-\\u9fa5]+楼)(\\d+)");
        Matcher matcher = buildingRoomPattern.matcher(userInput);
        if (matcher.find()) {
            entities.put("building", matcher.group(1));
            entities.put("room_number", matcher.group(2));
        }

        // 匹配职务+办公室模式，如"党委副书记办公室"
        Pattern officePattern = Pattern.compile("([\\u4e00-\\u9fa5]+)(办公室)");
        matcher = officePattern.matcher(userInput);
        if (matcher.find()) {
            entities.put("office", matcher.group(1) + matcher.group(2));
        }
    }

    private IntentType determinePrimaryIntent(List<IntentType> detectedIntents,
                                            double locationScore,
                                            double peopleScore,
                                            double procedureScore) {
        if (detectedIntents.isEmpty()) {
            return IntentType.UNKNOWN;
        }

        // 如果有位置查询意图，优先返回
        if (detectedIntents.contains(IntentType.LOCATION_QUERY)) {
            return IntentType.LOCATION_QUERY;
        }

        // 否则返回分数最高的意图
        if (locationScore >= peopleScore && locationScore >= procedureScore) {
            return IntentType.LOCATION_QUERY;
        } else if (peopleScore >= locationScore && peopleScore >= procedureScore) {
            return IntentType.PEOPLE_QUERY;
        } else {
            return IntentType.PROCEDURE_QUERY;
        }
    }

    private String rewriteQuery(IntentType primaryIntent, List<String> keywords, Map<String, String> entities) {
        List<String> queryTerms = new ArrayList<>();

        switch (primaryIntent) {
            case LOCATION_QUERY:
                // 对于位置查询，优先使用具体的实体信息
                if (entities.containsKey("office")) {
                    queryTerms.add(entities.get("office"));
                }
                if (entities.containsKey("specific_location")) {
                    queryTerms.add(entities.get("specific_location"));
                }
                // 添加位置相关的关键词
                queryTerms.addAll(keywords.stream()
                        .filter(LOCATION_KEYWORDS::contains)
                        .collect(Collectors.toList()));
                break;

            case PEOPLE_QUERY:
                // 人员查询
                if (entities.containsKey("person_role")) {
                    queryTerms.add(entities.get("person_role"));
                }
                queryTerms.addAll(keywords.stream()
                        .filter(PEOPLE_KEYWORDS::contains)
                        .collect(Collectors.toList()));
                break;

            case PROCEDURE_QUERY:
                // 流程查询
                queryTerms.addAll(keywords.stream()
                        .filter(PROCEDURE_KEYWORDS::contains)
                        .collect(Collectors.toList()));
                break;

            default:
                queryTerms.addAll(keywords);
        }

        // 确保查询词不为空
        if (queryTerms.isEmpty()) {
            queryTerms.addAll(keywords);
        }

        // 去重并连接成查询字符串
        return queryTerms.stream()
                .distinct()
                .collect(Collectors.joining(" "));
    }

    private double calculateConfidence(IntentType primaryIntent,
                                     double locationScore,
                                     double peopleScore,
                                     double procedureScore) {
        double maxScore = Math.max(locationScore, Math.max(peopleScore, procedureScore));

        if (primaryIntent == IntentType.UNKNOWN) {
            return 0.0;
        }

        // 根据意图类型和分数计算置信度
        return Math.min(maxScore * 1.5, 1.0);
    }
}
